package com.wty.good.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.wty.commons.result.DataGrid;
import com.wty.good.pojo.CommentWty;
import com.wty.good.repository.CommentRepositoryWty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @Author:wangtianyu
 * @Date：Created on 2020/5/6 0006 22:06
 */
@Service
public class CommentServiceWty {

    @Autowired
    private CommentRepositoryWty commentRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增评论
     *
     * @param comment
     * @return
     */
    public CommentWty addComment(CommentWty comment) {
        // 使用分布式ID生成器生成主键 ：mybatis-plus的IdWorker
        comment.set_id(IdWorker.getIdStr());
        // 设置评论的时间
        comment.setCreateTime(new Date());
        // 设置评论的点赞数为0
        comment.setThumbUp(0L);
        return commentRepository.insert(comment);
    }

    /**
     * 修改评论
     *
     * @param comment
     * @return
     */
    public CommentWty updateComment(CommentWty comment) {
        // save 测试有问题
        // CommentWty commentData = commentRepository.save(comment);

        // 方法一：使用 template 自己封装 不是很通用
//        Query query = Query.query(Criteria.where("_id").is(comment.get_id())); // 修改的条件
//        Update update = Update.update("content",comment.getContent());
//        mongoTemplate.updateFirst(query,update,comment.getClass());
//        return commentRepository.findById(comment.get_id()).get();

        // 方法二：
        // 先查询数据
        CommentWty commentData = commentRepository.findById(comment.get_id()).get();
        // 拷贝修改的数据到目标数据：拷贝时忽略null
        BeanUtil.copyProperties(comment, commentData, CopyOptions.create(CommentWty.class, true));
        // 修改
        return commentRepository.save(commentData);
    }

    /**
     * 删除评论
     *
     * @param id
     * @return
     */
    public Boolean deleteCommentById(String id) {
        commentRepository.deleteById(id);
        return true;
    }

    /**
     * 根据商品ID查询评论 分页
     *
     * @param goodId
     * @param current
     * @param size
     * @return
     */
    public DataGrid<CommentWty> findCommentByIdAndPage(Long goodId, Long current, Long size) {
        DataGrid<CommentWty> dataGrid = new DataGrid<>();
        // 封装查询条件
        CommentWty comment = new CommentWty();
        comment.setGoodId(goodId);
        Example<CommentWty> example = Example.of(comment);
        // 封装分页条件

        Pageable pageable = PageRequest.of(Math.toIntExact(current - 1), Math.toIntExact(size));
        Page<CommentWty> page = commentRepository.findAll(example, pageable);
        dataGrid.setTotal(page.getTotalElements());
        dataGrid.setRows(page.getContent());
        return dataGrid;
    }

    /**
     * 点赞
     *
     * @param id
     * @return
     */
    public Boolean thumbUpAdd(Long userId, String id) {
        // 单节点 ：应该到 session 中获取 userId ；分布式 ：应该通过鉴权获取 userId
        // 这里的userId由客户端传递
        // 判断redis中的点赞关系：是否已经点赞
        String commentKey = "good_comment_" + id; // 确保每个评论都有一个key
        Boolean flag = redisTemplate.boundSetOps(commentKey).isMember(userId); // 查询这个set中是否包含 userId
        if (!flag) {
            // 如果点赞关系不存在 -> 修改 MongoDB 中的点赞数
            Query query = Query.query(Criteria.where("_id").is(id));
            Update update = new Update().inc("thumbUp", 1); // 点赞+1
            mongoTemplate.updateFirst(query, update, CommentWty.class);
            // 在redis中保存点赞关系
            redisTemplate.boundSetOps(commentKey).add(userId);
        }
        return flag;
    }

    /**
     * 自定义查询接口
     *
     * @param comment
     * @return
     */
    public List<CommentWty> findByGoodIdAndContentContains(CommentWty comment) {
        return commentRepository.findByGoodIdAndContentContains(comment.getGoodId(), comment.getContent());
    }
}
